home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / Source / DBL Pascal Library / DefProcs / SICN Cntl / SICN CDEF.p < prev    next >
Text File  |  1992-07-31  |  11KB  |  346 lines

  1. unit SICN_CDEF;
  2.  
  3. {David B. Lamkins, June 1991}
  4. {}
  5. {Revision History:}
  6. {    DBL, 2 March 1992 — Provided correct control value behavior for all variants.}
  7. {    DBL, 20 July 1992 — Initialized contrlMin and contrlMax so SetCtlValue will work.}
  8.  
  9. {This is a CDEF for a small–icon (SICN) button that provides the following features:}
  10. {    • Uses control title, rather than a separate dialog item or control title.}
  11. {    • Handles “showTitle” variant (CDEF ID*16+1) to display control title centered under icon.}
  12. {    • Handles “useWFont” variant (CDEF ID*16+8) to display title using window font.}
  13. {    • Recognizes HiliteControl to enable/disable button.}
  14. {    • Displays 16x16, 16x32 (CDEF ID*16+4), and 32x16 (CDEF ID*16+6) controls.}
  15. {    • Automatically increments or decrements control value for double-SICN controls.}
  16. {    • Automatically cycles control value for single–SICN controls.}
  17. {}
  18. {Use:}
  19. {    CNTL min = SICN resource ID.}
  20. {    CNTL title = title to display for showTitle variant.}
  21. {    CNTL proc ID = 112, 113, 116, 117, 118, 119, 120, 121, 124, 125, 126, or 127 (since this is CDEF 7).}
  22. {    CNTL max and refcon are unused.}
  23. {    DITL rect must be at least as large as CNTL rect, otherwise Dialog Mgr won't detect hit in control.}
  24. {    You can not use SetCtlMin to change the icons or increment on the fly…}
  25. {    Calling SetCtlValue changes the displayed icon(s).}
  26. {    If the dialog contains TE fields, “useWFont” requires special handling. The following is}
  27. {      derived from Apple's Q&A Stack:}
  28. {            theDialog := GetNewDialog(…);}
  29. {            SetPort(theDialog);}
  30. {            TextFont(…);}
  31. {            TextSize(…);}
  32. {            ShowWindow(theDialog);}
  33. {            for i := 1 to 3 do}
  34. {                if EventAvail(everyEvent, evt) then}
  35. {                    ;}
  36. {            with DialogPeek(theDialog)^.textH^^ do}
  37. {                begin}
  38. {                    txFont := theDialog^.txFont;}
  39. {                    txSize := theDialog^.txSize;}
  40. {                end;}
  41. {            InitCursor;}
  42. {            repeat}
  43. {                ModalDialog(…);}
  44. {                …}
  45. {            until …;}
  46. {            DisposDialog(theDialog);}
  47.  
  48. interface
  49.  
  50.     function main (varCode: Integer; theControl: ControlHandle; message: Integer; param: Longint): Longint;
  51.  
  52. implementation
  53.  
  54. {$SETC Debugging=False}
  55.  
  56.     function main;
  57.         const
  58.             calcCntlRgn = 10;        {new in System 6.x and 7.0}
  59.             calcThumbRgn = 11;    {new in System 6.x and 7.0}
  60.             titleInset = 1;
  61.             SICNlength = 32;
  62.             doubleIcon = 4;            {variant code}
  63.             horizDouble = 2;
  64.             showTitle = 1;
  65.             upPartCode = 1;        {our part codes}
  66.             dnPartCode = 2;
  67.  
  68.             horizDoubleIcon = doubleIcon + horizDouble;
  69.  
  70.  
  71.         type
  72.             PrivateData = record
  73.                     ourSICN: Handle;    {the SICN}
  74.                     maxValue: Integer;
  75.                     patGrey: Pattern;    {our own grey pattern - can't use globals}
  76.                     ourRgn: RgnHandle;    {the control's region for tracking hits}
  77.                     theIncrement: Integer;
  78.                     upRect: Rect;
  79.                     dnRect: Rect;
  80.                     ourBox: Rect;
  81.                 end;
  82.             DataPtr = ^PrivateData;
  83.             DataHandle = ^DataPtr;
  84.  
  85.         var
  86.             savePort: GrafPtr;        {original port during drawing}
  87.             saveFont: Integer;        {original font}
  88.             saveSize: Integer;        {original size}
  89.             saveFace: Style;        {original style}
  90.             centerLine: Integer;    {vertical center line of icon}
  91.             titleWidth: Integer;        {width of the title}
  92.             titleRect: Rect;            {bounding rect of the title}
  93.             textBaseline: Integer;    {vertical position of title}
  94.             info: FontInfo;            {font info for drawing title}
  95.             drawValue: Integer;    {contrlValue unless maxValue = 0, then 0}
  96.  
  97.         procedure PlotSICN (theSICN: Handle; index: Integer; frame: Rect);
  98.             var
  99.                 theBitmap: BitMap;        {bitmap for plotting SICN}
  100.                 savedState: SignedByte;
  101.                 ourPort: GrafPtr;
  102.         begin
  103.             if theSICN <> nil then
  104.                 begin
  105.                     savedState := HGetState(theSICN);
  106.                     HLock(theSICN);
  107.                     with theBitmap do
  108.                         begin
  109.                             baseAddr := Ptr(ORD(theSICN^) + SICNlength * index);
  110.                             rowBytes := 2;
  111.                             bounds := frame;
  112.                         end;
  113.                     GetPort(ourPort);
  114.                     CopyBits(theBitmap, ourPort^.portBits, theBitmap.bounds, theBitmap.bounds, srcCopy, nil);
  115.                     HSetState(theSICN, savedState);
  116.                 end;
  117.         end;
  118.  
  119.     begin {Main — Icon Button CDEF}
  120.         main := 0;        {we normally return a zero}
  121.         HLock(Handle(theControl));    {lock down the control data for the duration}
  122.         with theControl^^ do
  123.             begin
  124.  
  125.         {----- Initialization -----}
  126.                 if message = initCntl then
  127.                     begin
  128. {$IFC Debugging}
  129.                         DebugStr('initCntl');
  130. {$ENDC}
  131.                         contrlData := NewHandleClear(SIZEOF(PrivateData));    {allocate private storage}
  132.                         if contrlData <> nil then
  133.                             begin
  134.                                 HLock(contrlData);
  135.                                 with DataHandle(contrlData)^^ do
  136.                                     begin    {create our local bitmap data}
  137.                                         StuffHex(@patGrey, 'AA55AA55AA55AA55');
  138.                                         ourSICN := GetResource('SICN', contrlMin);    {get handle to our SICN}
  139.                                         if ourSICN <> nil then
  140.                                             begin
  141.                                                 maxValue := GetHandleSize(ourSICN) div (2 * SICNlength) - 1;
  142.                                                 theIncrement := 2;
  143.                                                 if BAND(varCode, doubleIcon) <> 0 then
  144.                                                     begin
  145.                                                         maxValue := maxValue div 2;
  146.                                                         theIncrement := theIncrement * 2;
  147.                                                     end;
  148.                                             end
  149.                                         else
  150.                                             maxValue := 0;
  151.                                         contrlMin := 0;
  152.                                         contrlMax := maxValue;
  153.                                         ourRgn := NewRgn;    {create a region to hold button/title outline}
  154.                                     end;
  155.                                 HUnLock(contrlData);
  156.                             end;
  157.                     end
  158.  
  159.         {----- Disposal -----}
  160.                 else if message = dispCntl then
  161.                     begin
  162. {$IFC Debugging}
  163.                         DebugStr('dispCntl');
  164. {$ENDC}
  165.             {Don't know who else might be using our SICNs, so leave them alone.}
  166.                         if contrlData <> nil then
  167.                             begin
  168.                                 DisposeRgn(DataHandle(contrlData)^^.ourRgn);    {done forever with this region}
  169.                                 DisposHandle(contrlData);    {don't need our local data anymore, either}
  170.                             end;
  171.                     end
  172.  
  173.                 else if contrlData <> nil then
  174.                     begin
  175.                         HLock(contrlData);    {lock down control's private data}
  176.                         with DataHandle(contrlData)^^ do
  177.                             case message of
  178.  
  179.         {----- Drawing -----}
  180.                                 drawCntl: 
  181.                                     begin
  182. {$IFC Debugging}
  183.                                         DebugStr('drawCntl');
  184. {$ENDC}
  185.                                         GetPort(savePort);    {make sure we have the right port}
  186.                                         SetPort(contrlOwner);
  187.                                         with contrlOwner^ do    {remember the original font}
  188.                                             begin
  189.                                                 saveFont := txFont;
  190.                                                 saveSize := txSize;
  191.                                                 saveFace := txFace;
  192.                                             end;
  193.                                         if BAND(varCode, useWFont) = 0 then        {if we need system font, set it}
  194.                                             begin
  195.                                                 TextSize(0);
  196.                                                 TextFont(0);
  197.                                             end;
  198.                                         TextFace([]);    {make sure we have a clean face}
  199.                                         GetFontInfo(info);    {measure the title}
  200. {$PUSH}
  201. {$R-}
  202.                                         titleWidth := TextWidth(@contrlTitle[1], 0, ORD(contrlTitle[0]));
  203. {$POP}
  204.                                         if contrlValue < 0 then    {make sure our control value is legitimate}
  205.                                             contrlValue := 0
  206.                                         else if contrlValue > maxValue then
  207.                                             if maxValue > 0 then
  208.                                                 contrlValue := maxValue
  209.                                             else
  210.                                                 contrlValue := 1;
  211.                                         ourBox := contrlRect;
  212.                                         with ourBox do    {force the rect to fit}
  213.                                             case BAND(varCode, doubleIcon + horizDouble) of
  214.                                                 0: 
  215.                                                     begin
  216.                                                         bottom := top + 16;
  217.                                                         right := left + 16;
  218.                                                         centerLine := left + 8;
  219.                                                         upRect := ourBox;
  220.                                                         SetRect(dnRect, 0, 0, 0, 0);
  221.                                                     end;
  222.                                                 doubleIcon: 
  223.                                                     begin
  224.                                                         bottom := top + 32;
  225.                                                         right := left + 16;
  226.                                                         centerLine := left + 8;
  227.                                                         upRect := ourBox;
  228.                                                         upRect.bottom := top + 16;
  229.                                                         dnRect := ourBox;
  230.                                                         dnRect.top := upRect.bottom;
  231.                                                     end;
  232.                                                 horizDoubleIcon: 
  233.                                                     begin
  234.                                                         bottom := top + 16;
  235.                                                         right := left + 32;
  236.                                                         centerLine := left + 16;
  237.                                                         upRect := ourBox;
  238.                                                         upRect.left := ourBox.left + 16;
  239.                                                         dnRect := ourBox;
  240.                                                         dnRect.right := upRect.left;
  241.                                                     end;
  242.                                             end;
  243.                                         with info, titleRect do
  244.                                             begin    {position the control title and establish its bounding rect}
  245.                                                 top := ourBox.bottom;
  246.                                                 bottom := top + ascent + descent + leading;
  247.                                                 left := centerLine - titleWidth div 2;
  248.                                                 right := left + titleWidth;
  249.                                                 textBaseline := bottom - descent;
  250.                                             end;
  251.                                         InsetRect(titleRect, -titleInset, 0);
  252.                                         OpenRgn;    {make our region include the icon and the label}
  253.                                         FrameRect(ourBox);
  254.                                         if BAND(varCode, showTitle) <> 0 then
  255.                                             FrameRect(titleRect);
  256.                                         CloseRgn(ourRgn);    {save the control's region for future reference}
  257.                                         if contrlVis <> 0 then {if the control is visible…}
  258.                                             if ourSICN <> nil then    {…and the SICN is present…}
  259.                                                 begin    {draw the control}
  260.                                                     LoadResource(ourSICN);
  261.                                                     if BAND(varCode, showTitle) <> 0 then
  262.                                                         begin    {draw the title}
  263.                                                             EraseRect(titleRect);
  264.                                                             MoveTo(titleRect.left + titleInset, textBaseline);
  265.                                                             DrawString(contrlTitle);
  266.                                                         end;
  267.                                                     if maxValue > 0 then
  268.                                                         drawValue := contrlValue
  269.                                                     else
  270.                                                         drawValue := 0;
  271.                                                     case contrlHilite of
  272.                                                         0, 255:    {display normal control}
  273.                                                             begin
  274.                                                                 PlotSICN(ourSICN, drawValue * theIncrement, upRect);
  275.                                                                 PlotSICN(ourSICN, drawValue * theIncrement + 2, dnRect);
  276.                                                             end;
  277.                                                         1:    {display active control — ‘up’ pressed}
  278.                                                             begin
  279.                                                                 PlotSICN(ourSICN, drawValue * theIncrement + 1, upRect);
  280.                                                                 if maxValue = 0 then
  281.                                                                     contrlValue := 1
  282.                                                                 else if (theIncrement = 2) & (maxValue = contrlValue) then
  283.                                                                     contrlValue := 0
  284.                                                                 else
  285.                                                                     contrlValue := contrlValue + 1;
  286.                                                             end;
  287.                                                         2:     {display active control — ‘dn’ pressed}
  288.                                                             begin
  289.                                                                 PlotSICN(ourSICN, drawValue * theIncrement + 3, dnRect);
  290.                                                                 contrlValue := contrlValue - 1;
  291.                                                             end;
  292.                                                     end;
  293.                                                     if contrlHilite = 255 then
  294.                                                         begin    {grey out disabled control}
  295.                                                             PenPat(patGrey);
  296.                                                             PenMode(patBic);
  297.                                                             PaintRect(ourBox);
  298.                                                             PaintRect(titleRect);
  299.                                                         end;
  300.                                                 end
  301.                                             else
  302.                                                 begin    {no icon? draw a blank…}
  303.                                                     PenPat(patGrey);
  304.                                                     PaintRect(ourBox);
  305.                                                 end;
  306.                                         TextFont(saveFont);    {set everything back the way it was}
  307.                                         TextSize(saveSize);
  308.                                         TextFace(saveFace);
  309.                                         SetPort(savePort);
  310.                                     end;
  311.  
  312.         {----- Testing -----}
  313.                                 testCntl: 
  314.                                     begin
  315. {$IFC Debugging}
  316.                                         DebugStr('testCntl');
  317. {$ENDC}
  318.                                         if (contrlHilite <> 255) then
  319.                                             if PtInRect(Point(param), upRect) then
  320.                                                 main := upPartCode
  321.                                             else if PtInRect(Point(param), dnRect) then
  322.                                                 main := dnPartCode;
  323.                                     end;
  324.  
  325.         {----- Regions -----}
  326.                                 calcCRgns, calcCntlRgn: 
  327.                                     begin
  328. {$IFC Debugging}
  329.                                         DebugStr('calcCRgns, calcCntlRgn');
  330. {$ENDC}
  331.                                         if (message <> calcCRgns) or not BTST(param, 31) then
  332.                                             CopyRgn(ourRgn, RgnHandle(param));    {return control region}
  333.                                     end;
  334.  
  335.                                 otherwise
  336.                                     ;    {don't handle other messages}
  337.  
  338.                             end;
  339.                         HUnLock(contrlData);
  340.                     end;
  341.             end;
  342.         HUnLock(Handle(theControl));
  343.     end;
  344.  
  345.  
  346. end.